package com.ruoyi.face.service.impl;

import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.FaceVerifyRequest;
import com.baidu.aip.face.MatchRequest;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.IdUtils;
import com.ruoyi.face.domain.SysUserFace;
import com.ruoyi.face.domain.vo.FaceVerifyResult;
import com.ruoyi.face.mapper.SysUserFaceMapper;
import com.ruoyi.face.service.IFaceService;
import com.ruoyi.system.api.RemoteFileService;
import com.ruoyi.system.api.domain.SysFile;
import com.ruoyi.system.api.model.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 百度AI人脸识别服务实现
 *
 * @author ruoyi
 */
@Service
@Slf4j
public class BaiduAIFaceServiceImpl implements IFaceService {
    @Autowired
    private SysUserFaceMapper userFaceMapper;

    @Autowired
    private RemoteFileService remoteFileService;

    @Value("${baidu.ai.appId}")
    private String appId;

    @Value("${baidu.ai.apiKey}")
    private String apiKey;

    @Value("${baidu.ai.secretKey}")
    private String secretKey;

    @Value("${face.similarity-threshold:80}")
    private double similarityThreshold;

    /**
     * 获取百度AI人脸识别客户端
     */
    private AipFace getAipFaceClient() {
        AipFace client = new AipFace(appId, apiKey, secretKey);
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);
        return client;
    }

    @Override
    public SysUserFace registerFace(Long userId, String faceImage) {
        if (userId == null || StringUtils.isEmpty(faceImage)) {
            throw new ServiceException("用户ID和人脸图片不能为空");
        }

        try {
            // 1. 解码Base64图片数据
            byte[] imageData = Base64Util.decode(faceImage);
            if (imageData == null || imageData.length == 0) {
                throw new ServiceException("人脸图片解码失败");
            }

            // 2. 上传人脸图片到文件服务
            InputStream inputStream = new ByteArrayInputStream(imageData);
            MultipartFile multipartFile = new CommonsMultipartFile(
                "face.jpg", "face.jpg", "image/jpeg", inputStream);

            R<SysFile> fileResult = remoteFileService.upload(multipartFile);
            if (!R.isSuccess(fileResult) || fileResult.getData() == null) {
                throw new ServiceException("人脸图片上传失败: " + fileResult.getMsg());
            }

            // 3. 调用人脸检测API获取人脸特征
            AipFace client = getAipFaceClient();
            HashMap<String, String> options = new HashMap<>();
            options.put("face_field", "face_token");
            options.put("max_face_num", "1");
            options.put("face_type", "LIVE");
            options.put("liveness_control", "NORMAL");

            org.json.JSONObject result = client.detect(
                new String(imageData, StandardCharsets.UTF_8), "BASE64", options);

            if (result.getInt("error_code") != 0) {
                throw new ServiceException("人脸检测失败: " + result.getString("error_msg"));
            }

            // 4. 解析人脸特征并保存
            org.json.JSONArray faceList = result.getJSONObject("result").getJSONArray("face_list");
            if (faceList.length() == 0) {
                throw new ServiceException("未检测到人脸");
            }

            String faceToken = faceList.getJSONObject(0).getString("face_token");

            SysUserFace userFace = new SysUserFace();
            userFace.setUserId(userId);
            userFace.setFaceToken(faceToken);
            userFace.setFaceImageUrl(fileResult.getData().getUrl());
            userFace.setCreateTime(new Date());
            userFace.setUpdateTime(new Date());
            userFace.setStatus("0"); // 正常状态

            userFaceMapper.insert(userFace);
            return userFace;

        } catch (IOException e) {
            log.error("人脸注册异常: {}", e.getMessage(), e);
            throw new ServiceException("人脸注册失败，请稍后重试");
        }
    }

    @Override
    public FaceVerifyResult verifyFace(Long userId, String faceImage) {
        if (userId == null || StringUtils.isEmpty(faceImage)) {
            throw new ServiceException("用户ID和人脸图片不能为空");
        }

        // 1. 获取用户已注册的人脸信息
        List<SysUserFace> faceList = userFaceMapper.selectUserFaceByUserId(userId);
        if (faceList.isEmpty()) {
            throw new ServiceException("用户未注册人脸信息");
        }

        try {
            // 2. 准备百度AI人脸比对请求
            AipFace client = getAipFaceClient();
            List<String> faceTokens = faceList.stream()
                .map(SysUserFace::getFaceToken)
                .collect(Collectors.toList());

            // 3. 构造比对请求
            List<MatchRequest> requests = new ArrayList<>();
            requests.add(new MatchRequest(faceImage, "BASE64"));

            // 4. 逐个比对已注册人脸
            FaceVerifyResult verifyResult = new FaceVerifyResult();
            verifyResult.setVerified(false);
            verifyResult.setScore(0);

            for (String faceToken : faceTokens) {
                HashMap<String, String> options = new HashMap<>();
                options.put("liveness_control", "NORMAL");

                org.json.JSONObject result = client.verifyUser(faceToken, requests, options);
                if (result.getInt("error_code") != 0) {
                    log.warn("人脸比对失败: {}", result.getString("error_msg"));
                    continue;
                }

                // 5. 解析比对结果
                double score = result.getJSONObject("result").getDouble("score");
                if (score >= similarityThreshold) {
                    verifyResult.setVerified(true);
                    verifyResult.setScore(score);
                    verifyResult.setVerifyToken(IdUtils.fastUUID());
                    verifyResult.setExpireTime(new Date(System.currentTimeMillis() + 5 * 60 * 1000)); // 5分钟有效期
                    return verifyResult;
                }
            }

            return verifyResult;

        } catch (Exception e) {
            log.error("人脸验证异常: {}", e.getMessage(), e);
            throw new ServiceException("人脸验证失败，请稍后重试");
        }
    }

    @Override
    public List<SysUserFace> getFaceListByUserId(Long userId) {
        if (userId == null) {
            return Collections.emptyList();
        }
        return userFaceMapper.selectUserFaceByUserId(userId);
    }

    @Override
    public boolean deleteFace(Long faceId) {
        if (faceId == null) {
            throw new ServiceException("人脸ID不能为空");
        }

        SysUserFace userFace = userFaceMapper.selectById(faceId);
        if (userFace == null) {
            throw new ServiceException("人脸信息不存在");
        }

        // 删除人脸信息
        int rows = userFaceMapper.deleteById(faceId);
        if (rows > 0 && StringUtils.isNotEmpty(userFace.getFaceImageUrl())) {
            // 异步删除人脸图片
            try {
                remoteFileService.delete(userFace.getFaceImageUrl());
            } catch (Exception e) {
                log.error("人脸图片删除失败: {}", e.getMessage());
            }
        }
        return rows > 0;
    }
}